//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Mapping Application Block
//===============================================================================

using System.Data;
using System.Collections.ObjectModel;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder;
using EntLibContrib.Mapping.Instrumentation;

namespace EntLibContrib.Mapping
{
	/// <summary>
	/// This interface defines the contract that must be implemented by all mappers. 
	/// </summary>
	[CustomFactory(typeof(MapperCustomFactory))]
	public interface IMapper
	{
		#region Properties
		/// <summary>
		/// Gets the mapper name.
		/// </summary>
		/// <value>The name.</value>
		string Name
		{
			get;
		}

		/// <summary>
		/// Gets the table name.
		/// </summary>
		/// <value>The table name.</value>
		string TableName
		{
			get;
		}

		/// <summary>
		/// Gets the map dictionary.
		/// </summary>
		/// <value>A dictionary of maps.</value>
		MapDictionary Maps
		{
			get;
		}

		/// <summary>
		/// Gets or sets the instrumentation provider.
		/// </summary>
		/// <value>The instrumentation provider.</value>
		MappingInstrumentationProvider InstrumentationProvider
		{
			get;
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Maps a data transfer object to a single domain object.
		/// </summary>
		/// <typeparam name="T">The domain object type</typeparam>
		/// <param name="dataTransferObject">The data transfer object.</param>
		/// <returns>A populated domain object</returns>
		/// <remarks>
		/// 	<para>If the table name is null then the first table in the DataSet is used.</para>
		/// 	<para>If there are multiple rows in the table then only the first row is considered.</para>
		/// </remarks>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
		T ToDomainObject<T>(DataSet dataTransferObject) where T : class;

		/// <summary>
		/// Maps a data transfer object to a collection of domain objects.
		/// </summary>
		/// <typeparam name="T">The domain object type</typeparam>
		/// <param name="dataTransferObject">The data transfer object.</param>
		/// <returns>A collection of populated domain objects</returns>
		/// <remarks>
		/// 	<para>If the table name is null then the first table in the DataSet is used.</para>
		/// 	<para>Each row in the table is mapped to a domain object.</para>
		/// </remarks>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
		Collection<T> ToDomainObjectCollection<T>(DataSet dataTransferObject) where T : class;

		/// <summary>
		/// Maps a single domain object to a data transfer object.
		/// </summary>
		/// <typeparam name="T">The domain object type</typeparam>
		/// <param name="domainObject">The domain object.</param>
		/// <returns>A populated data transfer object</returns>
		/// <remarks>
		/// 	<para>If the table name is null then the table in the DataSet will be called the same as the domain object type.</para>
		/// 	<para>The table will contain just one row.</para>
		/// </remarks>
		DataSet FromDomainObject<T>(T domainObject) where T : class;

		/// <summary>
		/// Maps a collection of domain objects to a data transfer object.
		/// </summary>
		/// <typeparam name="T">The domain object type</typeparam>
		/// <param name="domainObjectCollection">The domain object collection.</param>
		/// <returns>A populated data transfer object</returns>
		/// <remarks>
		/// 	<para>If the table name is null then the table in the DataSet will be called the same as the domain object type.</para>
		/// 	<para>The table will contain a row for each domain object in the collection.</para>
		/// 	<para>The domain object collection must contain only one type (or supertype set).</para>
		/// </remarks>
		DataSet FromDomainObjectCollection<T>(Collection<T> domainObjectCollection) where T : class;
		#endregion
	}
}